package com.monolithiot.sso.service.impl;

import com.monolithiot.sso.common.entity.Authorization;
import com.monolithiot.sso.common.entity.User;
import com.monolithiot.sso.common.exception.ServiceUnforeseenException;
import com.monolithiot.sso.common.util.AuthorizationUtil;
import com.monolithiot.sso.common.util.DateUtil;
import com.monolithiot.sso.common.util.IdentityUtil;
import com.monolithiot.sso.dao.BaseMapper;
import com.monolithiot.sso.dao.mapper.AuthorizationMapper;
import com.monolithiot.sso.service.AuthorizationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 2018/12/12 Create by 郭文梁
 * AuthorizationServiceImpl
 * 授权业务服务实现
 *
 * @author 郭文梁
 * @date 2018/12/12
 */
@Service
public class AuthorizationServiceImpl extends BaseServiceImpl<Authorization> implements AuthorizationService {
    private final AuthorizationMapper authorizationMapper;

    @Autowired
    public AuthorizationServiceImpl(AuthorizationMapper authorizationMapper) {
        this.authorizationMapper = authorizationMapper;
    }

    @Override
    BaseMapper<Authorization> getMapper() {
        return authorizationMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Authorization getAuthorization(User user, int expireIn) {
        Authorization authorization = findAvailableByUser(user);

        if (authorization != null) {
            //已存在未过期的授权，则更新授权信息
            return touch(authorization, expireIn);
        }

        //创建新的授权
        Authorization freshAuth = Authorization.forUser(user);
        Date now = DateUtil.now();
        freshAuth.setCreateTime(now);
        freshAuth.setLastActivityTime(now);
        freshAuth.setToken(IdentityUtil.randomPrettyUUID());
        freshAuth.setExpireIn(expireIn);
        Authorization res = save(freshAuth);
        if (res == null) {
            throw new ServiceUnforeseenException("Could not save authorization " + freshAuth);
        }
        return res;
    }

    @Override
    public Authorization findByUser(User user) {
        Authorization query = Authorization.forUser(user);
        return authorizationMapper.selectOne(query);
    }

    @Override
    public Authorization findAvailableByUser(User user) {
        return authorizationMapper.selectAvailableByUserId(user.getId());
    }

    @Override
    public Authorization findByTokenWithUser(String token) {
        return authorizationMapper.selectByTokenWithUser(token);
    }

    @Override
    public Authorization findByToken(String token) {
        Authorization query = new Authorization();
        query.setToken(token);
        Authorization authorization = authorizationMapper.selectOne(query);
        if (authorization == null || AuthorizationUtil.isOverdue(authorization)) {
            return null;
        }
        return authorization;
    }

    @Override
    public Authorization touch(Authorization authorization, int expireIn) {
        authorization.setExpireIn(expireIn);
        authorization.setLastActivityTime(DateUtil.now());
        return update(authorization);
    }

    @Override
    public int deleteOverdue() {
        return authorizationMapper.deleteOverdue();
    }

    @Override
    public Authorization deleteByUser(User user) {
        Authorization query = new Authorization();
        query.setUserId(user.getId());
        return delete(query);
    }
}
